package com.rybbaby.tss.core.code.generate.view.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import com.rybbaby.tss.core.code.generate.view.bean.Views;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import com.rybbaby.tss.core.code.generate.view.bean.Controller;
import com.rybbaby.tss.core.code.generate.view.bean.View;
import com.rybbaby.tss.core.utils.StringUtils;

/**
 * @author 谢进伟
 * @description 视图配置文件 操作工具
 * @createDate 2016年11月12日 下午1:48:18
 */
public class ViewPropertiesReadUtil {
	
	public static void storeView(Views views , String properteisFilePath) {
		storeViewToXml(views);
		storeViewToProperties(views , properteisFilePath);
	}
	
	/**
	 * 保存视图文件为properties文件
	 *
	 * @param views
	 *            视图配置
	 * @param properteisFilePath
	 *            保存路径
	 */
	public static void storeViewToProperties(Views views , String properteisFilePath) {
		StringBuffer setting = new StringBuffer();
		String line = "-----------------------------";
		String line1 = "#######################################";
		setting.append("#").append(line1).append(" 此资源文件为所有 ").append(views.getModule()).append(" 模块 ").append(views.getDescribe()).append(line1);
		List<Controller> controllers = views.getControllers();
		for(Controller controller : controllers) {
			String name = controller.getName();
			setting.append("\n\n#").append(line).append(name).append(" views").append(line);
			List<View> viewList = controller.getViews();
			for(View view : viewList) {
				String describe = view.getDescribe();
				String key = view.getKey();
				String path2 = view.getPath();
				setting.append("\n#").append(describe);
				setting.append("\n").append(key).append(" = ").append(path2);
			}
		}
		File properties = new File(properteisFilePath);
		OutputStream output = null;
		try {
			if(!properties.exists()) {
				File parentFile = properties.getParentFile();
				if(!parentFile.exists()) {
					parentFile.mkdirs();
				}
				properties.createNewFile();
			}
			output = new FileOutputStream(properties);
			IOUtils.write(setting.toString().getBytes() , output);
			IOUtils.closeQuietly(output);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 保存视图配置文件
	 *
	 * @param views
	 *            视图配置
	 */
	public static void storeViewToXml(Views views) {
		OutputStream os = null;
		try {
			os = new FileOutputStream(views.getPath());
			Document document = DocumentHelper.createDocument();
			Element root = document.addElement("views");
			addElement(root , views.getModule() , "module");
			addElement(root , views.getDescribe() , "describe");
			List<Controller> controllers = views.getControllers();
			for(Controller controller : controllers) {
				Element controllerElement = root.addElement("controller");
				addElement(controllerElement , controller.getName() , "name");
				List<View> viewList = controller.getViews();
				for(View view : viewList) {
					Element viewElement = addElement(controllerElement , null , "view");
					addElement(viewElement , view.getDescribe() , "describe");
					addElement(viewElement , view.getKey() , "key");
					addElement(viewElement , view.getPath() , "path");
				}
			}
			OutputFormat format = OutputFormat.createPrettyPrint();
			format.setEncoding("utf-8");
			XMLWriter writer = new XMLWriter(os , format);
			writer.write(document);
			writer.flush();
			writer.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(os);
		}
	}
	
	/**
	 * 解析视图配置文件
	 *
	 * @param xmlFilePath
	 *            视图配置文件路径
	 * @return
	 */
	public static Views parseViewXml(String xmlFilePath) {
		Views views = new Views();
		views.setPath(xmlFilePath);
		FileInputStream fis = null;
		try {
			DocumentFactory factory = new DocumentFactory();
			SAXReader reader = new SAXReader(factory);
			File xmlFile = new File(xmlFilePath);
			if(xmlFile.exists()) {
				fis = new FileInputStream(xmlFile);
				Document document = reader.read(fis);
				Element root = document.getRootElement();
				if(root != null) {
					List<?> controllerNodes = root.elements("controller");
					List<Controller> controllerList = new ArrayList<Controller>();
					for(Object cnObj : controllerNodes) {
						if(cnObj instanceof Element) {
							Element cn = (Element)cnObj;
							List<?> viewsNode = cn.elements("view");
							List<View> viewList = new ArrayList<View>();
							for(Object viewNodeObj : viewsNode) {
								if(viewNodeObj instanceof Element) {
									Element viewNode = (Element)viewNodeObj;
									View view = new View();
									view.setDescribe(getElementValue(viewNode , "describe"));
									view.setKey(getElementValue(viewNode , "key"));
									view.setPath(getElementValue(viewNode , "path"));
									viewList.add(view);
								}
							}
							Controller controller = new Controller();
							controller.setName(cn.element("name").getStringValue());
							controller.setViews(viewList);
							controllerList.add(controller);
						}
					}
					views.setDescribe(getElementValue(root , "describe"));
					views.setModule(getElementValue(root , "module"));
					views.setControllers(controllerList);
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} finally {
			IOUtils.closeQuietly(fis);
		}
		return views;
	}
	
	/**
	 * 获取元素中指定子元素的内容
	 *
	 * @param parentNodeElement
	 *            父元素
	 * @param tagName
	 *            子元素标签
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private static String getElementValue(Element parentNodeElement , String tagName) throws UnsupportedEncodingException {
		return unicodeToChinese(parentNodeElement.element(tagName).getStringValue());
	}
	
	/**
	 * unicode转换成中文
	 *
	 * @param unicodeStr
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	private static String unicodeToChinese(String unicodeStr) throws UnsupportedEncodingException {
		if(unicodeStr.indexOf("\\u") > -1) {
			StringBuffer sb = new StringBuffer();
			for(int i = 0 ; i < unicodeStr.length() - 2 ; i++) {
				String ch = unicodeStr.substring(i , i + 2);
				if(ch.equals("\\u")) {
					sb.append((char)Integer.parseInt(unicodeStr.substring(i + 2 , i + 6) , 16));
				} else {
					sb.append(unicodeStr.charAt(i));
				}
			}
			unicodeStr = sb.toString().replaceAll("u[0-9A-F]{0,4}" , "");
		}
		return new String(unicodeStr.getBytes() , "UTF-8");
	}
	
	/**
	 * 添加元素
	 *
	 * @param parentElement
	 *            父元素
	 * @param text
	 *            内容
	 * @param tagName
	 *            标签名
	 * @return
	 */
	private static Element addElement(Element parentElement , String text , String tagName) {
		Element element = parentElement.addElement(tagName);
		if(StringUtils.isNotBlank(text)) {
			element.addText(text);
		}
		return element;
	}
}
